﻿using EnvDTE80;
using Microsoft.VisualStudio.Shell;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Xml;
using System.Xml.XPath;

namespace PhotoStartPageControl
{
    /// <summary>
    /// Interaction logic for MyControl.xaml
    /// </summary>
    public partial class BackgroundImageControl : UserControl
    {
        #region Feilds

        public static readonly DependencyProperty _startPageImageProperty = DependencyProperty.Register("StartPageImage", typeof(string), typeof(BackgroundImageControl), (PropertyMetadata)null);
        private XmlNamespaceManager _xmlnsm;
        private int _imageSource = -1;
        private string _filePath;
        private string _imageUrl;
        private string _rssFeedUrl;
        private string _imageUrlXmlNode;
        private string _imageUrlXmlAttribute;
        private bool _useXmlAttribute;
        private StartPageSettings _settings;

        #endregion

        #region Properties

        public string FilePath
        {
            get
            {
                if (string.IsNullOrEmpty(_filePath))
                    _filePath = StartPageSettings.RetrieveString("FILE_PATH");

                return this._filePath;
            }
            set
            {
                _filePath = value;
                StartPageSettings.StoreString("FILE_PATH", _filePath);
            }
        }

        public int ImageSource
        {
            get
            {
                if (_imageSource == -1)
                {
                    int result = -1;
                    
                    if (int.TryParse(StartPageSettings.RetrieveString("IMAGE_SOURCE"), out result))
                        _imageSource = result;
                }

                return this._imageSource;
            }
            set
            {
                _imageSource = value;
                StartPageSettings.StoreString("IMAGE_SOURCE", _imageSource.ToString());
            }
        }

        public string ImageUrl
        {
            get
            {
                if (string.IsNullOrEmpty(_imageUrl))
                    _imageUrl = StartPageSettings.RetrieveString("IMAGE_URL");
                
                return this._imageUrl;
            }
            set
            {
                _imageUrl = value;
                StartPageSettings.StoreString("IMAGE_URL", _imageUrl);
            }
        }

        public string ImageUrlXmlNode
        {
            get
            {
                if (string.IsNullOrEmpty(_imageUrlXmlNode))
                {
                    _imageUrlXmlNode = StartPageSettings.RetrieveString("IMAGE_URL_XML_NODE");

                    if (string.IsNullOrEmpty(_imageUrlXmlNode))
                        ImageUrlXmlNode = "/x:rss/x:channel/x:item/x:enclosure";
                }

                return _imageUrlXmlNode;
            }
            set
            {
                _imageUrlXmlNode = value;
                StartPageSettings.StoreString("IMAGE_URL_XML_NODE", _imageUrlXmlNode);
            }
        }

        public string ImageUrlXmlAttribute
        {
            get
            {
                if (string.IsNullOrEmpty(this._imageUrlXmlAttribute))
                {
                    _imageUrlXmlAttribute = StartPageSettings.RetrieveString("IMAGE_URL_XML_ATTRIBUTE");

                    if (string.IsNullOrEmpty(_imageUrlXmlAttribute))
                        ImageUrlXmlAttribute = "url";
                }

                return _imageUrlXmlAttribute;
            }
            set
            {
                _imageUrlXmlAttribute = value;
                StartPageSettings.StoreString("IMAGE_URL_XML_ATTRIBUTE", _imageUrlXmlAttribute);
            }
        }

        public string RssFeedUrl
        {
            get
            {
                if (string.IsNullOrEmpty(_rssFeedUrl))
                {
                    _rssFeedUrl = StartPageSettings.RetrieveString("IMAGE_FEED_URL");

                    if (string.IsNullOrEmpty(_rssFeedUrl))
                        RssFeedUrl = "http://feeds.feedburner.com/bingimages";
                }

                return _rssFeedUrl;
            }
            set
            {
                _rssFeedUrl = value;
                StartPageSettings.StoreString("IMAGE_FEED_URL", _rssFeedUrl);
            }
        }

        public string StartPageImage
        {
            get
            {
                return (string)GetValue(_startPageImageProperty);
            }
            set
            {
                SetValue(_startPageImageProperty, (object)value);
            }
        }

        /// <summary>
        /// Return a StartPageSettings object.
        ///
        /// Use: StartPageSettings.StoreString("MySettingName", "MySettingValue");
        /// Use: string value = StartPageSettings.RetrieveString("MySettingName");
        ///
        /// Note: As this property is using the Start Page tool window DataContext to retrieve the Visual Studio DTE, 
        /// this property can only be used after the UserControl is loaded and the inherited DataContext is set.
        /// </summary>
        private StartPageSettings StartPageSettings
        {
            get
            {
                if (_settings == null)
                {
                    DTE2 dte = Utilities.GetDTE(DataContext);
                    ServiceProvider serviceProvider = Utilities.GetServiceProvider(dte);
                    _settings = new StartPageSettings(serviceProvider);
                }

                return _settings;
            }
        }

        public bool UseXmlAttribute
        {
            get
            {
                string str = StartPageSettings.RetrieveString("IMAGE_URL_USE_XML_ATTRIBUTE");
                bool.TryParse(str, out _useXmlAttribute);

                if (!bool.TryParse(str, out _useXmlAttribute))
                    return false;
                else
                    return this._useXmlAttribute;
            }
            set
            {
                _useXmlAttribute = value;
                StartPageSettings.StoreString("IMAGE_URL_USE_XML_ATTRIBUTE", value.ToString());
            }
        }

        #endregion

        #region Constructors

        static BackgroundImageControl()
        {
        }

        public BackgroundImageControl()
        {
            InitializeComponent();
        }

        #endregion

        #region Methods

        private static XmlNamespaceManager GetXmlNameSpaceManager(XPathNavigator xpn)
        {
            xpn.MoveToFollowing(XPathNodeType.Element);
            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xpn.NameTable);
            namespaceManager.AddNamespace("x", xpn.NamespaceURI);

            foreach (KeyValuePair<string, string> keyValuePair in (IEnumerable<KeyValuePair<string, string>>)xpn.GetNamespacesInScope(XmlNamespaceScope.All))
            {
                namespaceManager.AddNamespace(keyValuePair.Key, keyValuePair.Value);
            }
            
            return namespaceManager;
        }

        public void LoadBackgroundImage()
        {
            try
            {
                switch (ImageSource)
                {
                    case 0:     // Use Local File

                        StartPageImage = FilePath;

                        break;

                    case 1:     // Use Online Image

                        StartPageImage = ImageUrl;

                        break;

                    case 2:     // Use RSS Feed

                        XPathNavigator navigator = new XPathDocument(RssFeedUrl).CreateNavigator();
                        _xmlnsm = BackgroundImageControl.GetXmlNameSpaceManager(navigator);
                        XPathNavigator xpathNavigator = navigator.SelectSingleNode(ImageUrlXmlNode, (IXmlNamespaceResolver)_xmlnsm);

                        if (xpathNavigator == null)
                            return;

                        if (UseXmlAttribute)
                            StartPageImage = xpathNavigator.GetAttribute(ImageUrlXmlAttribute, xpathNavigator.NamespaceURI);
                        else
                            StartPageImage = xpathNavigator.Value;

                        break;
                }
            }
            catch (Exception ex)
            {
                // Currently just swallow so that the exception does not bring down VS.
            }
        }

        public void UpdateImageRssFeedInformation(int imageSource, string filePath, string imageUrl, string rssFeed, string imageUrlXmlNode, bool useXmlAttribute, string imageUrlXmlAttribute)
        {
            ImageSource = imageSource;

            switch (ImageSource)
            {
                case 0:     // Use Local File

                    if (string.IsNullOrWhiteSpace(filePath))
                        throw new ArgumentException("The filePath argument cannot be null or whitespace.");

                    FilePath = filePath;

                    break;

                case 1:     // Use Online Image

                    if (string.IsNullOrWhiteSpace(imageUrl))
                        throw new ArgumentException("The imageUrl argument cannot be null or whitespace.");
                    
                    ImageUrl = imageUrl;

                    break;

                case 2:     // Use RSS Feed

                    if (string.IsNullOrWhiteSpace(rssFeed))
                        throw new ArgumentException("The rssFeed argument cannot be null or whitespace.");

                    if (string.IsNullOrWhiteSpace(imageUrlXmlNode))
                        throw new ArgumentException("The imageUrlXmlNode argument cannot be null or whitespace.");

                    if (useXmlAttribute & string.IsNullOrWhiteSpace(imageUrlXmlAttribute))
                        throw new ArgumentException("The imageUrlXmlAttribute argument cannot be null or whitespace.");

                    RssFeedUrl = rssFeed;
                    ImageUrlXmlNode = imageUrlXmlNode;
                    UseXmlAttribute = useXmlAttribute;
                    ImageUrlXmlAttribute = ImageUrlXmlAttribute;                    

                    break;
            }

            LoadBackgroundImage();
        }

        #endregion

        #region Event Handlers

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            LoadBackgroundImage();
        }

        private void ImageOptionsButton_Click(object sender, RoutedEventArgs e)
        {
            new BackgroundImageSettings(this).Show();
        }

        #endregion
    }
}